
import bus from './bus';
import Hammer from "hammerjs";
import dicomParser from "dicom-parser";
import * as cornerstone from "cornerstone-core";
import * as cornerstoneMath from "cornerstone-math";
import * as cornerstoneWADOImageLoader from "cornerstone-wado-image-loader";
import * as cornerstoneWebImageLoader from "cornerstone-web-image-loader";
// import * as cornerstoneTools from "@cornerstonejs/tools";
import cornerstoneTools from "cornerstone-tools";
import _ from 'lodash';
import './initCornerstone'

const toolNameList = ["RectangleRoi", "FreehandRoi"];
class Cornerstone {
  element: any;
  imageBase64List: any[];
  tools:any[];
  currnetToolName: string;
  toolDisabled: boolean;
  width: number;
  height: number;
  measurementData: any;
  elementString: string;
  currentImageIndex: number;
  seriesUid: number;
  nidus:any;
  isView: boolean;
  seriesNumber: number;
  stack:any;
  scrollToIndex: Function;
  constructor(options:any){
    this.seriesNumber = options?.seriesNumber || 0;
    this.seriesUid = options?.seriesUid;
    this.elementString = options?.element;
    this.element = document.querySelector(options?.element);
    this.currnetToolName = "";
    this.imageBase64List = options?.imageBase64List || [];
    this.tools = options?.tools || [];
    this.toolDisabled = options?.toolDisabled === undefined ? false : options?.toolDisabled;
    this.width = options.width || 800;
    this.height = options.height || 640;
    this.nidus = options?.nidus || {};
    this.isView = options?.isView
    cornerstone.enable(this.element);
    this.currentImageIndex = 0;
    
    // this.init();
    
    this.displayImage(0);
    this.scrollToIndex = cornerstoneTools.importInternal('util/scrollToIndex');
    // console.log(cornerstoneTools.EVENTS)
    this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_ADDED, this.measurementAdded.bind(this));
    this.element.addEventListener(cornerstoneTools.EVENTS.MEASUREMENT_MODIFIED, _.debounce(this.measurementModified, 300));
    this.element.addEventListener(cornerstoneTools.EVENTS.MOUSE_CLICK, this.singleClick.bind(this));
  }
  singleClick(e:any){
    let flag = true;
    toolNameList.forEach((toolName:string) => {
      const items:any = cornerstoneTools.getToolState(this.element, toolName);
      const states = (items?.data || []).slice();
      states.forEach((item:any) => {
        if(item.active && flag ){
          flag = false;
          bus.emit("Cornerstone.singleClick", item.uuid);
        }
      })
    })
  }
  //更新
  measurementModified(e:any){
    const { measurementData, toolName } = e.detail;
    if( measurementData && ["RectangleRoi", "FreehandRoi"].includes(toolName) ){  
      console.log("modified", e);
      bus.emit("Cornerstone.measurementModified", [this.currnetToolName, JSON.parse(JSON.stringify(measurementData))]);
    }
  }
  //添加
  measurementAdded(e:any){
    const { measurementData, toolName } = e.detail;
    if( measurementData && ["RectangleRoi", "FreehandRoi"].includes(toolName) ){
      console.log("Adde", e);
      bus.emit("Cornerstone.measurementAdded", [this.currnetToolName, JSON.parse(JSON.stringify(measurementData))]);
    }
  }
  init(){
    const imageIds = this.imageBase64List.map((imageBase64, index)=>{
      return `example://${this.seriesUid}/${(index+1)}.jpg`
    })
    this.stack = {
      seriesDescription: "",
      stackId: this.seriesUid,
      imageIds,
      seriesIndex: this.seriesNumber,
      currentImageIdIndex: 0,
      frameRate: 0,
    }
    cornerstone.registerImageLoader('example', (imageId:any) :any =>{
      const index = imageIds.findIndex(_imageId=> imageId === _imageId)
      return this.getExampleImage(imageId, this.imageBase64List[index]);
    });
    cornerstoneTools.addStackStateManager(this.element, ['stack'])
    cornerstoneTools.addToolState(this.element, 'stack', this.stack)
    cornerstoneTools.stackPrefetch.enable(this.element)
  }
  displayImage(imageIndex: number, callback:Function = ()=>{}){
    if( imageIndex < 0 || imageIndex >= this.imageBase64List.length  ) return;
    const img = this.imageBase64List[imageIndex || 0];
    cornerstone.registerImageLoader('example', (imageId:any) :any =>{
      return this.getExampleImage(imageId, img);
    });
    cornerstone.loadAndCacheImage(`example://${this.seriesUid}/${(imageIndex+1)}.jpg`).then((image:any)=> {
      setTimeout(()=>{
        this.currentImageIndex = imageIndex;
        cornerstone.displayImage(this.element, image);
        callback();
      })
    });
  }
  setScrollToIndex(index:number){
    this.displayImage(index);
  }
  
  getExampleImage(imageId:any, imageBase64:any) {
    let [width, height] = [this.width, this.height];
    const img = document.createElement("img");
    img.src = imageBase64;
    // 使用Image对象获取图像长和宽，并准备转化为canvas对象
    img.width = width;
    img.height = height;
  
    function loadPixelData () {
      // 用canvas获取图像数据的像素矩阵（数组）
      const canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      canvas.getContext("2d")?.drawImage(img, 0, 0);
      const pixelData_obj:any = canvas.getContext("2d")?.getImageData(0,0,canvas.width,canvas.height);    // 获取画布上的图像像素矩阵
      const pixelData = pixelData_obj.data;
      return pixelData;
    }
  
    const image = {
      imageId: imageId,
      minPixelValue : 0,
      maxPixelValue : 255,
      slope: 1.0,
      intercept: 0,
      windowCenter : 127,
      windowWidth : 256,
      getPixelData: loadPixelData,	// 要求图像的像素矩阵
      rows: height,
      columns: width,
      height: height,
      width: width,
      color: true,	// 注意：为彩色图像
      rgba: true,		// 注意：使用rgba表示（canvas直接导出）
      columnPixelSpacing: .8984375,
      rowPixelSpacing: .8984375,
      sizeInBytes: width * height * 4
    };
    return {
      promise: new Promise((resolve) => {
        resolve(image);
      }),
      cancelFn: undefined
    };
  }
  setToolDisabled( toolName:string ){
    this.toolDisabled = true
    const tool = cornerstoneTools[`${toolName}Tool`];
    // cornerstoneTools.removeTool(tool);
    cornerstoneTools.setToolDisabled(toolName, { mouseButtonMask: 1 });
  }
  setToolName(toolName:string){
    this.currnetToolName = toolName

  }
  setToolActive(toolName:string){
    const tool = cornerstoneTools[`${toolName}Tool`];
    cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });
    if( this.currnetToolName === "RectangleRoi" ){
      cornerstoneTools.setToolEnabled("FreehandRoi", { mouseButtonMask: 1 })
    } else {
      cornerstoneTools.setToolEnabled("RectangleRoi", { mouseButtonMask: 1 })
    }
  }
  setToolEnabled(toolName:string){
    const tool = cornerstoneTools[`${toolName}Tool`];
    cornerstoneTools.setToolEnabled(toolName, { mouseButtonMask: 1 });
  }

  toggleToolDisabled(statusText: string){
    // console.log("statusText", statusText, "this.currnetToolName:"+this.currnetToolName, )
    if( statusText === 'enabled'  ){
      this.toolDisabled = true;
      cornerstoneTools.setToolEnabled("RectangleRoi", { mouseButtonMask: 1 })
      cornerstoneTools.setToolEnabled("FreehandRoi", { mouseButtonMask: 1 })
    } 
    if( statusText === "passive" ){
      cornerstoneTools.setToolPassive("RectangleRoi", { mouseButtonMask: 1 });
      cornerstoneTools.setToolPassive("FreehandRoi", { mouseButtonMask: 1 });
    }
    if( statusText === "active" ){
      cornerstoneTools.setToolActive(this.currnetToolName, { mouseButtonMask: 1 });
      if( this.currnetToolName === "RectangleRoi" ){
        cornerstoneTools.setToolEnabled("FreehandRoi", { mouseButtonMask: 1 })
      } else {
        cornerstoneTools.setToolEnabled("RectangleRoi", { mouseButtonMask: 1 })
      }
    }
  }
  //调窗工具
  toggleToolDisabledWwwc( disabled:boolean, toolName:string ){
    if( disabled ){
      cornerstoneTools.setToolDisabled(toolName, { mouseButtonMask: 1 })
    } else {
      cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });
    }
  }

  //初始化的时候执行一次
  addToolState(nidusList:any, isView:boolean){
    this.isView = isView
    nidusList.child.forEach((item: any, index:number) => {
      const { child } = item;
      child.forEach((it:any)=> {
        const { data, toolName, labelIndex } = it
        // this.setToolActive(toolName);
        this.setToolEnabled(toolName)
        const imageId = `example://${this.seriesUid}/${labelIndex}.jpg`
        cornerstoneTools.globalImageIdSpecificToolStateManager.addImageIdToolState(imageId, toolName, data);
      })
    });
    //恢复之前工具
    if(this.currnetToolName === '' || this.toolDisabled){
      cornerstoneTools.setToolPassive('RectangleRoi')
      cornerstoneTools.setToolPassive('FreehandRoi')
    }else{
      this.setToolActive(this.currnetToolName);
    }

    cornerstone.updateImage(this.element);
    if( isView ){
      setTimeout(()=>{
        cornerstoneTools.setToolEnabled('RectangleRoi')
        cornerstoneTools.setToolEnabled('FreehandRoi')
      },100)
    }
  }
  setToolVisible(item:any){
    const { toolName, hide } = item;
    const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    for(let ts in toolState){
      let data = toolState[ts][toolName]?.data || []
      data.forEach((dataItem:any)=> {
        if(dataItem.uuid === item.data.uuid){
          if( toolName ){
            dataItem.visible = !hide
          }
        }
      });
    }
    cornerstone.updateImage(this.element);
  }
  setStateColor(item:any, color:string){

    const { toolName } = item;
    const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    for(let ts in toolState){
      let data = toolState[ts][toolName]?.data || []
      data.forEach((dataItem:any)=> {
        if(dataItem.uuid === item.data.uuid){
          dataItem.color = color;
        }
      });
    }
    cornerstone.updateImage(this.element);
  }
  removeToolState(item:any){
    const { toolName } = item;
    const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState
    for(let ts in toolState){
      let data = toolState[ts][toolName]?.data || []
      if(data.length === 0) continue
      toolState[ts][toolName].data = data.filter((it:any) => item.data.uuid !== it.uuid)
    }
    cornerstone.updateImage(this.element);
  }
  
}

export default Cornerstone;
